﻿#pragma once

#include "../../../http/http_base.hh"
#include "../lua_export_class.h"

#include "../../box_std_allocator.hh"
#include <string>
#include <unordered_set>

namespace kratos {
namespace service {
class ServiceBox;
}
} // namespace kratos

namespace kratos {
namespace console {
class Console;
struct ConsoleSwitch;
struct ConsoleSelection;
} // namespace console
} // namespace kratos

namespace kratos {
namespace lua {

namespace LuaUtil {
class LuaState;
}

class LuaServiceImpl;

/**
 * @brief Console类lua导出包装
 */
class LuaConsole : public LuaExportClass {
  kratos::service::ServiceBox *box_{nullptr}; ///< 服务容器
  lua_State *L_{nullptr};                     ///< lua虚拟机
  LuaServiceImpl *service_{nullptr};          ///< 服务容器
  int lua_reg_key_{LUA_NOREF};                ///< Lua注册表key
  /**
   * @brief 开关回调
   */
  struct SwtichCallback {
    std::string name;           ///< 开关名称
    int refresh_key{LUA_NOREF}; ///< 刷新回调索引
    int change_key{LUA_NOREF};  ///< 变化回调索引
  };
  /**
   * @brief 选项回调
   */
  struct SelectionCallback {
    std::string name;           ///< 开关名称
    int refresh_key{LUA_NOREF}; ///< 刷新回调索引
    int change_key{LUA_NOREF};  ///< 变化回调索引
  };
  int index_{1};
  using SwitchCallbackInfoMap =
      kratos::service::PoolUnorederedMap<int, SwtichCallback>;
  SwitchCallbackInfoMap switch_cb_info_map_; ///< 开关回调信息表
  using SelectionCallbackInfoMap =
      kratos::service::PoolUnorederedMap<int, SelectionCallback>;
  SelectionCallbackInfoMap selection_cb_info_map_; ///< 选项回调信息表

public:
  /**
   * @brief 构造
   * @param box 服务容器
   * @param L 虚拟机
   * @param service lua服务
   */
  LuaConsole(kratos::service::ServiceBox *box, lua_State *L,
             LuaServiceImpl *service);
  /**
   * 析构
   */
  virtual ~LuaConsole();
  virtual auto do_register() -> bool override;
  virtual auto update(std::time_t ms) -> void override;
  virtual auto do_cleanup() -> void override;

private:
  auto new_index() -> int;
  auto add_switch_callback(const SwtichCallback &cb) -> int;
  auto remove_switch_callback(const SwtichCallback &cb) -> void;
  auto add_selection_callback(const SelectionCallback &cb) -> int;
  auto remove_selection_callback(const SelectionCallback &cb) -> void;
  void switch_refresh_cb(kratos::console::Console &console,
                         kratos::console::ConsoleSwitch &cs);
  bool switch_change_cb(kratos::console::Console &console, bool on_off,
                        std::string &result);
  void selection_refresh_cb(kratos::console::Console &console,
                            kratos::console::ConsoleSelection &cs);
  bool selection_change_cb(kratos::console::Console &console,
                           const std::string &name, std::string &result);

private:
  static int lua_add_switch(lua_State *l);
  static int lua_add_selection(lua_State *l);
};

} // namespace lua
} // namespace kratos
